package model;

import org.mybeans.dao.DAOException;
import org.mybeans.factory.BeanFactory;
import org.mybeans.factory.BeanFactoryException;
import org.mybeans.factory.BeanTable;
import org.mybeans.factory.DuplicateKeyException;
import org.mybeans.factory.MatchArg;
import org.mybeans.factory.RollbackException;
import org.mybeans.factory.Transaction;

import databeans.EntityClass;
import interfas.EntityClassInterface;

public class EntityClassDAO implements EntityClassInterface {

	private BeanFactory<EntityClass> factory;
	private int ecid = 1;
	
	public EntityClassDAO() throws DAOException {
		try {
			BeanTable<EntityClass> table = BeanTable.getInstance(EntityClass.class, "entityclass");
			if (!table.exists())
				table.create("ecid");
			
			table.setIdleConnectionCleanup(true);
			factory = table.getFactory();
			
			if (factory.getBeanCount() > 0)
				ecid = factory.match(MatchArg.max("ecid"))[0].getEcid() + 1;
			
		} catch (BeanFactoryException e) {
			throw new DAOException(e);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public void create(EntityClass ec, SurveyDAO surveyDAO) throws DAOException {
		try {
			// Check for foreign key constraint
			if (surveyDAO.lookup(ec.getSid()) == null) {
				throw new DAOException("sid must exist in survey table");
			}
			// Check for duplicate key
			if (lookupBySidName(ec.getSid(), ec.getName()) != null) {
				throw new DAOException("An entityclass with sid " + ec.getSid() + " and name " + ec.getName() + " already exists");
			}
			
			Transaction.begin();
			EntityClass dbec = factory.create(ec.getEcid());
			factory.copyInto(ec, dbec);
			ecid++;
			Transaction.commit();
		} catch (DuplicateKeyException e) {
			throw new DAOException("An entityclass with ecid " + ec.getEcid() + " already exists");
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}

	public EntityClass lookup(int ecid) throws DAOException {
		try {
			return factory.lookup(ecid);
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	//Another way of lookup, (sid, name) tuple should be unique
	public EntityClass lookupBySidName(int sid, String name) throws DAOException {
		try {
			EntityClass[] ecarray = factory.match(MatchArg.equals("sid", sid), MatchArg.equals("name", name));
			if (ecarray == null || ecarray.length == 0)
				return null;
			else
				return ecarray[0];
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public EntityClass[] getEntityClassBySid(int sid) throws DAOException {
		try {
			return factory.match(MatchArg.equals("sid", sid));
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public void delete(int ecid) throws DAOException {
		try {
			Transaction.begin();
			EntityClass dbec = lookup(ecid);
			if (dbec == null)
				throw new DAOException("EntityClass with ecid " + ecid + " doesn't exist");
			factory.delete(ecid);
			Transaction.commit();
		} catch (RollbackException e) {
			throw new DAOException(e);
		} finally {
			if (Transaction.isActive())
				Transaction.rollback();
		}
	}
	
	public int size() throws DAOException {
		try {
			return factory.getBeanCount();
		} catch (RollbackException e) {
			throw new DAOException(e);
		}
	}
	
	public int getEcid() {
		return ecid;
	}
}
